home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / cpu / mips / mips.c < prev    next >
C/C++ Source or Header  |  2000-05-14  |  39KB  |  1,356 lines

  1. /*
  2.  * MIPS emulator for the MAME project written by smf
  3.  *
  4.  * Work in progress, there is still much to do.
  5.  *
  6.  */
  7.  
  8. #include "driver.h"
  9. #include "cpuintrf.h"
  10. #include "state.h"
  11. #include "mamedbg.h"
  12. #include "mips.h"
  13.  
  14. #define EXC_INT ( 0 )
  15. #define EXC_TLBL ( 2 )
  16. #define EXC_TLBS ( 3 )
  17. #define EXC_ADEL ( 4 )
  18. #define EXC_ADES ( 5 )
  19. #define EXC_SYS ( 8 )
  20. #define EXC_BP ( 9 )
  21. #define EXC_RI ( 10 )
  22. #define EXC_OVF ( 12 )
  23.  
  24. #define CP0_RANDOM ( 1 )
  25. #define CP0_BADVADDR ( 8 )
  26. #define CP0_SR ( 12 )
  27. #define CP0_CAUSE ( 13 )
  28. #define CP0_EPC ( 14 )
  29.  
  30. #define SR_IEC ( 1L << 0 )
  31. #define SR_KUC ( 1L << 1 )
  32. #define SR_ISC ( 1L << 16 )
  33. #define SR_SWC ( 1L << 17 )
  34. #define SR_TS  ( 1L << 21 )
  35. #define SR_BEV ( 1L << 22 )
  36. #define SR_RE ( 1L << 25 )
  37.  
  38. #define CAUSE_BD ( 0x80000000 )
  39.  
  40. /* there are more registers but the debugger interface is limited to 127 */
  41. static UINT8 mips_reg_layout[] =
  42. {
  43.     MIPS_PC, MIPS_OC, -1,
  44.     MIPS_HI, MIPS_LO, -1,
  45.     -1,
  46.     MIPS_R0, MIPS_R1, -1,
  47.     MIPS_R2, MIPS_R3, -1,
  48.     MIPS_R4, MIPS_R5, -1,
  49.     MIPS_R6, MIPS_R7, -1,
  50.     MIPS_R8, MIPS_R9, -1,
  51.     MIPS_R10, MIPS_R11, -1,
  52.     MIPS_R12, MIPS_R13, -1,
  53.     MIPS_R14, MIPS_R15, -1,
  54.     MIPS_R16, MIPS_R17, -1,
  55.     MIPS_R18, MIPS_R19, -1,    
  56.     MIPS_R20, MIPS_R21, -1,
  57.     MIPS_R22, MIPS_R23, -1,
  58.     MIPS_R24, MIPS_R25, -1,
  59.     MIPS_R26, MIPS_R27, -1,
  60.     MIPS_R28, MIPS_R29, -1,
  61.     MIPS_R30, MIPS_R31, -1,
  62.     -1,
  63.     MIPS_CP0R0, MIPS_CP0R1, -1,
  64.     MIPS_CP0R2, MIPS_CP0R3, -1,
  65.     MIPS_CP0R4, MIPS_CP0R5, -1,
  66.     MIPS_CP0R6, MIPS_CP0R7, -1,
  67.     MIPS_CP0R8, MIPS_CP0R9, -1,
  68.     MIPS_CP0R10, MIPS_CP0R11, -1,
  69.     MIPS_CP0R12, MIPS_CP0R13, -1,
  70.     MIPS_CP0R14, MIPS_CP0R15, -1,
  71.     MIPS_CP0R16, MIPS_CP0R17, -1,
  72.     MIPS_CP0R18, MIPS_CP0R19, -1,
  73.     MIPS_CP0R20, MIPS_CP0R21, -1,
  74.     MIPS_CP0R22, MIPS_CP0R23, -1,
  75.     MIPS_CP0R24, MIPS_CP0R25, -1,
  76.     MIPS_CP0R26, MIPS_CP0R27, -1,
  77.     MIPS_CP0R28, MIPS_CP0R29, -1,
  78.     MIPS_CP0R30, MIPS_CP0R31, 0
  79. };
  80.  
  81. static UINT8 mips_win_layout[] = {
  82.     45, 0,35,13,    /* register window (top right) */
  83.      0, 0,44,13,    /* disassembler window (left, upper) */
  84.      0,14,44, 8,    /* memory #1 window (left, middle) */
  85.     45,14,35, 8,    /* memory #2 window (lower) */
  86.      0,23,80, 1     /* command line window (bottom rows) */
  87. };
  88.  
  89. typedef struct
  90. {
  91.     UINT32 op;
  92.     UINT32 pc;
  93.     UINT32 nextop;
  94.     UINT32 nextpc;
  95.     UINT32 irq;
  96.     UINT32 hi;
  97.     UINT32 lo;
  98.     UINT32 r[ 32 ];
  99.     UINT32 cp0r[ 32 ];
  100. } mips_cpu_context;
  101.  
  102. mips_cpu_context mips;
  103. UINT32 context_pc = 0;
  104.  
  105. int mips_ICount = 0;
  106.  
  107. static void mips_exception( int exception )
  108. {
  109.     mips.cp0r[ CP0_CAUSE ] = ( mips.cp0r[ CP0_CAUSE ] & 0xffffff83 ) | ( exception << 2 );
  110.     if( mips.pc != mips.nextpc - 4 )
  111.     {
  112.         mips.cp0r[ CP0_EPC ] = mips.pc - 4;
  113.         mips.cp0r[ CP0_CAUSE ] |= CAUSE_BD;
  114.     }
  115.     else
  116.     {
  117.         mips.cp0r[ CP0_EPC ] = mips.pc;
  118.         mips.cp0r[ CP0_CAUSE ] &= ~CAUSE_BD;
  119.     }
  120.     mips.cp0r[ CP0_SR ] = ( mips.cp0r[ CP0_SR ] & 0xffffffc0 ) | ( ( mips.cp0r[ CP0_SR ] << 2 ) & 0x3f );
  121.     if( mips.cp0r[ CP0_SR ] & SR_BEV )
  122.     {
  123.         mips_set_pc( 0xbfc00180 );
  124.     }
  125.     else
  126.     {
  127.         mips_set_pc( 0x80000080 );
  128.     }
  129. }
  130.  
  131. void mips_stop( void )
  132. {
  133. #ifdef MAME_DEBUG
  134.     extern int debug_key_pressed;
  135.     debug_key_pressed = 1;
  136.     CALL_MAME_DEBUG;
  137. #endif
  138. }
  139.  
  140. INLINE void mips_set_nextpc( UINT32 adr )
  141. {
  142.     mips.pc = mips.nextpc;
  143.     mips.op = mips.nextop;
  144.     if( ( adr & ( ( ( mips.cp0r[ CP0_SR ] & 0x02 ) << 31 ) | 3 ) ) != 0 )
  145.     {
  146.         mips.cp0r[ CP0_BADVADDR ] = adr;
  147.         mips_exception( EXC_ADEL );
  148.     }
  149.     else
  150.     {
  151.         change_pc32( adr );
  152.         mips.nextpc = adr;
  153.         mips.nextop = cpu_readop32( mips.nextpc );
  154.     }
  155. }
  156.  
  157. INLINE void mips_advance_pc( void )
  158. {
  159.     mips.pc = mips.nextpc;
  160.     mips.op = mips.nextop;
  161.     mips.nextpc += 4;
  162.     mips.nextop = cpu_readop32( mips.nextpc );
  163. }
  164.  
  165. void mips_reset( void *param )
  166. {
  167.     mips.cp0r[ CP0_RANDOM ] = 63;
  168.     mips.cp0r[ CP0_SR ] = ( mips.cp0r[ CP0_SR ] & ~( SR_TS | SR_SWC | SR_KUC | SR_IEC ) ) | SR_BEV;
  169.     mips_set_pc( 0xbfc00000 );
  170. }
  171.  
  172. void mips_exit( void )
  173. {
  174. }
  175.  
  176. int mips_execute( int cycles )
  177. {
  178.     mips_ICount = cycles;
  179.     do
  180.     {
  181.         mips.op = cpu_readop32(mips.pc);
  182.         mips.pc += 4;
  183.  
  184.         CALL_MAME_DEBUG;
  185.  
  186.         switch( INS_OP( mips.op ) )
  187.         {
  188.         case OP_SPECIAL:
  189.             switch( INS_FUNCT( mips.op ) )
  190.             {
  191.             case FUNCT_SLL:
  192.                 if( INS_RD( mips.op ) != 0 )
  193.                 {
  194.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RT( mips.op ) ] << INS_SHAMT( mips.op );
  195.                 }
  196.                 mips_advance_pc();
  197.                 break;
  198.             case FUNCT_SRL:
  199.                 if( INS_RD( mips.op ) != 0 )
  200.                 {
  201.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RT( mips.op ) ] >> INS_SHAMT( mips.op );
  202.                 }
  203.                 mips_advance_pc();
  204.                 break;
  205.             case FUNCT_SRA:
  206.                 if( INS_RD( mips.op ) != 0 )
  207.                 {
  208.                     mips.r[ INS_RD( mips.op ) ] = (INT32)mips.r[ INS_RT( mips.op ) ] >> INS_SHAMT( mips.op );
  209.                 }
  210.                 mips_advance_pc();
  211.                 break;
  212.             case FUNCT_SLLV:
  213.                 if( INS_RD( mips.op ) != 0 )
  214.                 {
  215.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RT( mips.op ) ] << ( mips.r[ INS_RS( mips.op ) ] & 31 );
  216.                 }
  217.                 mips_advance_pc();
  218.                 break;
  219.             case FUNCT_SRLV:
  220.                 if( INS_RD( mips.op ) != 0 )
  221.                 {
  222.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RT( mips.op ) ] >> ( mips.r[ INS_RS( mips.op ) ] & 31 );
  223.                 }
  224.                 mips_advance_pc();
  225.                 break;
  226.             case FUNCT_SRAV:
  227.                 if( INS_RD( mips.op ) != 0 )
  228.                 {
  229.                     mips.r[ INS_RD( mips.op ) ] = (INT32)mips.r[ INS_RT( mips.op ) ] >> ( mips.r[ INS_RS( mips.op ) ] & 31 );
  230.                 }
  231.                 mips_advance_pc();
  232.                 break;
  233.             case FUNCT_JR:
  234.                 if( INS_RD( mips.op ) != 0 )
  235.                 {
  236.                     mips_exception( EXC_RI );
  237.                 }
  238.                 else
  239.                 {
  240.                     mips_set_nextpc( mips.r[ INS_RS( mips.op ) ] );
  241.                 }
  242.                 break;
  243.             case FUNCT_JALR:
  244.                 if( INS_RD( mips.op ) != 0 )
  245.                 {
  246.                     mips.r[ INS_RD( mips.op ) ] = mips.nextpc + 4;
  247.                 }
  248.                 mips_set_nextpc( mips.r[ INS_RS( mips.op ) ] );
  249.                 break;
  250.             case FUNCT_SYSCALL:
  251.                 mips_exception( EXC_SYS );
  252.                 break;
  253.             case FUNCT_BREAK:
  254.                 mips_exception( EXC_BP );
  255.                 break;
  256.             case FUNCT_MFHI:
  257.                 if( INS_RD( mips.op ) != 0 )
  258.                 {
  259.                     mips.r[ INS_RD( mips.op ) ] = mips.hi;
  260.                 }
  261.                 mips_advance_pc();
  262.                 break;
  263.             case FUNCT_MTHI:
  264.                 if( INS_RD( mips.op ) != 0 )
  265.                 {
  266.                     mips_exception( EXC_RI );
  267.                 }
  268.                 else
  269.                 {
  270.                     mips.hi = mips.r[ INS_RS( mips.op ) ];
  271.                 }
  272.                 mips_advance_pc();
  273.                 break;
  274.             case FUNCT_MFLO:
  275.                 if( INS_RD( mips.op ) != 0 )
  276.                 {
  277.                     mips.r[ INS_RD( mips.op ) ] = mips.lo;
  278.                 }
  279.                 mips_advance_pc();
  280.                 break;
  281.             case FUNCT_MTLO:
  282.                 if( INS_RD( mips.op ) != 0 )
  283.                 {
  284.                     mips_exception( EXC_RI );
  285.                 }
  286.                 else
  287.                 {
  288.                     mips.lo = mips.r[ INS_RS( mips.op ) ];
  289.                 }
  290.                 mips_advance_pc();
  291.                 break;
  292.             case FUNCT_MULT:
  293.                 if( INS_RD( mips.op ) != 0 )
  294.                 {
  295.                     mips_exception( EXC_RI );
  296.                 }
  297.                 else
  298.                 {
  299.                     INT64 res;
  300.                     res = MUL_64_32_32( (INT32)mips.r[ INS_RS( mips.op ) ], (INT32)mips.r[ INS_RT( mips.op ) ] );
  301.                     mips.lo = LO32_32_64( res );
  302.                     mips.hi = HI32_32_64( res );
  303.                     mips_advance_pc();
  304.                 }
  305.                 break;
  306.             case FUNCT_MULTU:
  307.                 if( INS_RD( mips.op ) != 0 )
  308.                 {
  309.                     mips_exception( EXC_RI );
  310.                 }
  311.                 else
  312.                 {
  313.                     UINT64 res;
  314.                     res = MUL_U64_U32_U32( (INT32)mips.r[ INS_RS( mips.op ) ], (INT32)mips.r[ INS_RT( mips.op ) ] );
  315.                     mips.lo = LO32_U32_U64( res );
  316.                     mips.hi = HI32_U32_U64( res );
  317.                     mips_advance_pc();
  318.                 }
  319.                 break;
  320.             case FUNCT_DIV:
  321.                 if( INS_RD( mips.op ) != 0 )
  322.                 {
  323.                     mips_exception( EXC_RI );
  324.                 }
  325.                 else
  326.                 {
  327.                     mips.lo = (INT32)mips.r[ INS_RS( mips.op ) ] / (INT32)mips.r[ INS_RT( mips.op ) ];
  328.                     mips.hi = (INT32)mips.r[ INS_RS( mips.op ) ] % (INT32)mips.r[ INS_RT( mips.op ) ];
  329.                     mips_advance_pc();
  330.                 }
  331.                 break;
  332.             case FUNCT_DIVU:
  333.                 if( INS_RD( mips.op ) != 0 )
  334.                 {
  335.                     mips_exception( EXC_RI );
  336.                 }
  337.                 else
  338.                 {
  339.                     mips.lo = mips.r[ INS_RS( mips.op ) ] / mips.r[ INS_RT( mips.op ) ];
  340.                     mips.hi = mips.r[ INS_RS( mips.op ) ] % mips.r[ INS_RT( mips.op ) ];
  341.                     mips_advance_pc();
  342.                 }
  343.                 break;
  344.             case FUNCT_ADD:
  345.                 {
  346.                     UINT32 res;
  347.                     res = mips.r[ INS_RS( mips.op ) ] + mips.r[ INS_RT( mips.op ) ];
  348.                     if( (INT32)( ( mips.r[ INS_RS( mips.op ) ] & mips.r[ INS_RT( mips.op ) ] & ~res ) | ( ~mips.r[ INS_RS( mips.op ) ] & ~mips.r[ INS_RT( mips.op ) ] & res ) ) < 0 )
  349.                     {
  350.                         mips_exception( EXC_OVF );
  351.                     }
  352.                     else
  353.                     {
  354.                         if( INS_RD( mips.op ) != 0 )
  355.                         {
  356.                             mips.r[ INS_RD( mips.op ) ] = res;
  357.                         }
  358.                         mips_advance_pc();
  359.                     }
  360.                 }
  361.                 break;
  362.             case FUNCT_ADDU:
  363.                 if( INS_RD( mips.op ) != 0 )
  364.                 {
  365.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] + mips.r[ INS_RT( mips.op ) ];
  366.                 }
  367.                 mips_advance_pc();
  368.                 break;
  369.             case FUNCT_SUB:
  370.                 {
  371.                     UINT32 res;
  372.                     res = mips.r[ INS_RS( mips.op ) ] - mips.r[ INS_RT( mips.op ) ];
  373.                     if( (INT32)( ( mips.r[ INS_RS( mips.op ) ] & ~mips.r[ INS_RT( mips.op ) ] & ~res ) | ( ~mips.r[ INS_RS( mips.op ) ] & mips.r[ INS_RT( mips.op ) ] & res ) ) < 0 )
  374.                     {
  375.                         mips_exception( EXC_OVF );
  376.                     }
  377.                     else
  378.                     {
  379.                         if( INS_RD( mips.op ) != 0 )
  380.                         {
  381.                             mips.r[ INS_RD( mips.op ) ] = res;
  382.                         }
  383.                         mips_advance_pc();
  384.                     }
  385.                 }
  386.                 break;
  387.             case FUNCT_SUBU:
  388.                 if( INS_RD( mips.op ) != 0 )
  389.                 {
  390.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] - mips.r[ INS_RT( mips.op ) ];
  391.                 }
  392.                 mips_advance_pc();
  393.                 break;
  394.             case FUNCT_AND:
  395.                 if( INS_RD( mips.op ) != 0 )
  396.                 {
  397.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] & mips.r[ INS_RT( mips.op ) ];
  398.                 }
  399.                 mips_advance_pc();
  400.                 break;
  401.             case FUNCT_OR:
  402.                 if( INS_RD( mips.op ) != 0 )
  403.                 {
  404.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] | mips.r[ INS_RT( mips.op ) ];
  405.                 }
  406.                 mips_advance_pc();
  407.                 break;
  408.             case FUNCT_XOR:
  409.                 if( INS_RD( mips.op ) != 0 )
  410.                 {
  411.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] ^ mips.r[ INS_RT( mips.op ) ];
  412.                 }
  413.                 mips_advance_pc();
  414.                 break;
  415.             case FUNCT_NOR:
  416.                 if( INS_RD( mips.op ) != 0 )
  417.                 {
  418.                     mips.r[ INS_RD( mips.op ) ] = ~( mips.r[ INS_RS( mips.op ) ] | mips.r[ INS_RT( mips.op ) ] );
  419.                 }
  420.                 mips_advance_pc();
  421.                 break;
  422.             case FUNCT_SLT:
  423.                 if( INS_RD( mips.op ) != 0 )
  424.                 {
  425.                     mips.r[ INS_RD( mips.op ) ] = (INT32)mips.r[ INS_RS( mips.op ) ] < (INT32)mips.r[ INS_RT( mips.op ) ];
  426.                 }
  427.                 mips_advance_pc();
  428.                 break;
  429.             case FUNCT_SLTU:
  430.                 if( INS_RD( mips.op ) != 0 )
  431.                 {
  432.                     mips.r[ INS_RD( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] < mips.r[ INS_RT( mips.op ) ];
  433.                 }
  434.                 mips_advance_pc();
  435.                 break;
  436.             default:
  437.                 mips_exception( EXC_RI );
  438.                 break;
  439.             }
  440.             break;
  441.         case OP_REGIMM:
  442.             switch( INS_RT( mips.op ) )
  443.             {
  444.             case RT_BLTZ:
  445.                 if( (INT32)mips.r[ INS_RS( mips.op ) ] < 0 )
  446.                 {
  447.                     mips_set_nextpc( mips.nextpc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) ) << 2 ) );
  448.                 }
  449.                 else
  450.                 {
  451.                     mips_advance_pc();
  452.                 }
  453.                 break;
  454.             case RT_BGEZ:
  455.                 if( (INT32)mips.r[ INS_RS( mips.op ) ] >= 0 )
  456.                 {
  457.                     mips_set_nextpc( mips.nextpc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) ) << 2 ) );
  458.                 }
  459.                 else
  460.                 {
  461.                     mips_advance_pc();
  462.                 }
  463.                 break;
  464.             case RT_BLTZAL:
  465.                 mips.r[ 31 ] = mips.nextpc + 4;
  466.                 if( (INT32)mips.r[ INS_RS( mips.op ) ] < 0 )
  467.                 {
  468.                     mips_set_nextpc( mips.nextpc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) ) << 2 ) );
  469.                 }
  470.                 else
  471.                 {
  472.                     mips_advance_pc();
  473.                 }
  474.                 break;
  475.             case RT_BGEZAL:
  476.                 mips.r[ 31 ] = mips.nextpc + 4;
  477.                 if( (INT32)mips.r[ INS_RS( mips.op ) ] >= 0 )
  478.                 {
  479.                     mips_set_nextpc( mips.nextpc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) ) << 2 ) );
  480.                 }
  481.                 else
  482.                 {
  483.                     mips_advance_pc();
  484.                 }
  485.                 break;
  486.             }
  487.             break;
  488.         case OP_J:
  489.             mips_set_nextpc( ( mips.nextpc & 0xF0000000 ) + ( INS_TARGET( mips.op ) << 2 ) );
  490.             break;
  491.         case OP_JAL:
  492.             mips.r[ 31 ] = mips.nextpc + 4;
  493.             mips_set_nextpc( ( mips.nextpc & 0xF0000000 ) + ( INS_TARGET( mips.op ) << 2 ) );
  494.             break;
  495.         case OP_BEQ:
  496.             if( mips.r[ INS_RS( mips.op ) ] == mips.r[ INS_RT( mips.op ) ] )
  497.             {
  498.                 mips_set_nextpc( mips.nextpc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) ) << 2 ) );
  499.             }
  500.             else
  501.             {
  502.                 mips_advance_pc();
  503.             }
  504.             break;
  505.         case OP_BNE:
  506.             if( mips.r[ INS_RS( mips.op ) ] != mips.r[ INS_RT( mips.op ) ] )
  507.             {
  508.                 mips_set_nextpc( mips.nextpc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) ) << 2 ) );
  509.             }
  510.             else
  511.             {
  512.                 mips_advance_pc();
  513.             }
  514.             break;
  515.         case OP_BLEZ:
  516.             if( INS_RT( mips.op ) != 0 )
  517.             {
  518.                 mips_exception( EXC_RI );
  519.             }
  520.             else if( (INT32)mips.r[ INS_RS( mips.op ) ] <= 0 )
  521.             {
  522.                 mips_set_nextpc( mips.nextpc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) ) << 2 ) );
  523.             }
  524.             else
  525.             {
  526.                 mips_advance_pc();
  527.             }
  528.             break;
  529.         case OP_BGTZ:
  530.             if( INS_RT( mips.op ) != 0 )
  531.             {
  532.                 mips_exception( EXC_RI );
  533.             }
  534.             else if( (INT32)mips.r[ INS_RS( mips.op ) ] > 0 )
  535.             {
  536.                 mips_set_nextpc( mips.nextpc + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) ) << 2 ) );
  537.             }
  538.             else
  539.             {
  540.                 mips_advance_pc();
  541.             }
  542.             break;
  543.         case OP_ADDI:
  544.             {
  545.                 UINT32 res,imm;
  546.                 imm = MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  547.                 res = mips.r[ INS_RS( mips.op ) ] + imm;
  548.                 if( (INT32)( ( mips.r[ INS_RS( mips.op ) ] & imm & ~res ) | ( ~mips.r[ INS_RS( mips.op ) ] & ~imm & res ) ) < 0 )
  549.                 {
  550.                     mips_exception( EXC_OVF );
  551.                 }
  552.                 else
  553.                 {
  554.                     if( INS_RT( mips.op ) != 0 )
  555.                     {
  556.                         mips.r[ INS_RT( mips.op ) ] = res;
  557.                     }
  558.                     mips_advance_pc();
  559.                 }
  560.             }
  561.             break;
  562.         case OP_ADDIU:
  563.             if( INS_RT( mips.op ) != 0 )
  564.             {
  565.                 mips.r[ INS_RT( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  566.             }
  567.             mips_advance_pc();
  568.             break;
  569.         case OP_SLTI:
  570.             if( INS_RT( mips.op ) != 0 )
  571.             {
  572.                 mips.r[ INS_RT( mips.op ) ] = (INT32)mips.r[ INS_RS( mips.op ) ] < MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  573.             }
  574.             mips_advance_pc();
  575.             break;
  576.         case OP_SLTIU:
  577.             if( INS_RT( mips.op ) != 0 )
  578.             {
  579.                 mips.r[ INS_RT( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] < (unsigned)MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  580.             }
  581.             mips_advance_pc();
  582.             break;
  583.         case OP_ANDI:
  584.             if( INS_RT( mips.op ) != 0 )
  585.             {
  586.                 mips.r[ INS_RT( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] & INS_IMMEDIATE( mips.op );
  587.             }
  588.             mips_advance_pc();
  589.             break;
  590.         case OP_ORI:
  591.             if( INS_RT( mips.op ) != 0 )
  592.             {
  593.                 mips.r[ INS_RT( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] | INS_IMMEDIATE( mips.op );
  594.             }
  595.             mips_advance_pc();
  596.             break;
  597.         case OP_XORI:
  598.             if( INS_RT( mips.op ) != 0 )
  599.             {
  600.                 mips.r[ INS_RT( mips.op ) ] = mips.r[ INS_RS( mips.op ) ] ^ INS_IMMEDIATE( mips.op );
  601.             }
  602.             mips_advance_pc();
  603.             break;
  604.         case OP_LUI:
  605.             if( INS_RT( mips.op ) != 0 )
  606.             {
  607.                 mips.r[ INS_RT( mips.op ) ] = INS_IMMEDIATE( mips.op ) << 16;
  608.             }
  609.             mips_advance_pc();
  610.             break;
  611.         case OP_COP0:
  612.             switch( INS_RS( mips.op ) )
  613.             {
  614.             case RS_MFC:
  615.                 mips.r[ INS_RT( mips.op ) ] = mips.cp0r[ INS_RD( mips.op ) ];
  616.                 mips_advance_pc();
  617.                 break;
  618.             case RS_CFC:
  619.                 /* not implemented */
  620.                 mips_stop();
  621.                 mips_advance_pc();
  622.                 break;
  623.             case RS_MTC:
  624.                 mips.cp0r[ INS_RD( mips.op ) ] = mips.r[ INS_RT( mips.op ) ];
  625.                 mips_advance_pc();
  626.                 break;
  627.             case RS_CTC:
  628.                 /* not implemented */
  629.                 mips_stop();
  630.                 mips_advance_pc();
  631.                 break;
  632.             case RS_BC:
  633.                 mips_stop();
  634.                 switch( INS_RT( mips.op ) )
  635.                 {
  636.                 case RT_BCF:
  637.                     /* not implemented */
  638.                     mips_stop();
  639.                     mips_advance_pc();
  640.                     break;
  641.                 case RT_BCT:
  642.                     /* not implemented */
  643.                     mips_stop();
  644.                     mips_advance_pc();
  645.                     break;
  646.                 }
  647.                 break;
  648.             default:
  649.                 switch( INS_CO( mips.op ) )
  650.                 {
  651.                 case 1:
  652.                     switch( INS_CF( mips.op ) )
  653.                     {
  654.                     case CF_RFE:
  655.                         mips.cp0r[ CP0_SR ] = ( mips.cp0r[ CP0_SR ] & 0xffffffe0 ) | ( ( mips.cp0r[ CP0_SR ] >> 2 ) & 0x1f );
  656.                         mips_advance_pc();
  657.                         break;
  658.                     default:
  659.                         /* not implemented */
  660.                         mips_stop();
  661.                         mips_advance_pc();
  662.                         break;
  663.                     }
  664.                     break;
  665.                 default:
  666.                     /* not implemented */
  667.                     mips_stop();
  668.                     mips_advance_pc();
  669.                     break;
  670.                 }
  671.                 break;
  672.             }
  673.             break;
  674.         case OP_COP1:
  675.             switch( INS_RS( mips.op ) )
  676.             {
  677.             case RS_MFC:
  678.                 /* not implemented */
  679.                 mips_stop();
  680.                 mips_advance_pc();
  681.                 break;
  682.             case RS_CFC:
  683.                 /* not implemented */
  684.                 mips_stop();
  685.                 mips_advance_pc();
  686.                 break;
  687.             case RS_MTC:
  688.                 /* not implemented */
  689.                 mips_stop();
  690.                 mips_advance_pc();
  691.                 break;
  692.             case RS_CTC:
  693.                 /* not implemented */
  694.                 mips_stop();
  695.                 mips_advance_pc();
  696.                 break;
  697.             case RS_BC:
  698.                 mips_stop();
  699.                 switch( INS_RT( mips.op ) )
  700.                 {
  701.                 case RT_BCF:
  702.                     /* not implemented */
  703.                     mips_stop();
  704.                     mips_advance_pc();
  705.                     break;
  706.                 case RT_BCT:
  707.                     /* not implemented */
  708.                     mips_stop();
  709.                     mips_advance_pc();
  710.                     break;
  711.                 }
  712.                 break;
  713.             default:
  714.                 mips_stop();
  715.                 switch( INS_CO( mips.op ) )
  716.                 {
  717.                 case 1:
  718.                     /* not implemented */
  719.                     mips_stop();
  720.                     mips_advance_pc();
  721.                     break;
  722.                 default:
  723.                     /* not implemented */
  724.                     mips_stop();
  725.                     mips_advance_pc();
  726.                     break;
  727.                 }
  728.                 break;
  729.             }
  730.             break;
  731.         case OP_COP2:
  732.             switch( INS_RS( mips.op ) )
  733.             {
  734.             case RS_MFC:
  735.                 /* not implemented */
  736.                 mips_stop();
  737.                 mips_advance_pc();
  738.                 break;
  739.             case RS_CFC:
  740.                 /* not implemented */
  741.                 mips_stop();
  742.                 mips_advance_pc();
  743.                 break;
  744.             case RS_MTC:
  745.                 /* not implemented */
  746.                 mips_stop();
  747.                 mips_advance_pc();
  748.                 break;
  749.             case RS_CTC:
  750.                 /* not implemented */
  751.                 mips_stop();
  752.                 mips_advance_pc();
  753.                 break;
  754.             case RS_BC:
  755.                 mips_stop();
  756.                 switch( INS_RT( mips.op ) )
  757.                 {
  758.                 case RT_BCF:
  759.                     /* not implemented */
  760.                     mips_stop();
  761.                     mips_advance_pc();
  762.                     break;
  763.                 case RT_BCT:
  764.                     /* not implemented */
  765.                     mips_stop();
  766.                     mips_advance_pc();
  767.                     break;
  768.                 }
  769.                 break;
  770.             default:
  771.                 mips_stop();
  772.                 switch( INS_CO( mips.op ) )
  773.                 {
  774.                 case 1:
  775.                     /* not implemented */
  776.                     mips_stop();
  777.                     mips_advance_pc();
  778.                     break;
  779.                 default:
  780.                     /* not implemented */
  781.                     mips_stop();
  782.                     mips_advance_pc();
  783.                     break;
  784.                 }
  785.                 break;
  786.             }
  787.             break;
  788.         case OP_LB:
  789.             if( mips.cp0r[ CP0_SR ] & SR_RE || mips.cp0r[ CP0_SR ] & SR_ISC )
  790.             {
  791.                 /* not implemented */
  792.                 mips_advance_pc();
  793.             }
  794.             else
  795.             {
  796.                 UINT32 adr;
  797.                 adr = mips.r[ INS_RS( mips.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  798.                 if( ( adr & ( ( mips.cp0r[ CP0_SR ] & 0x02 ) << 31 ) ) != 0 )
  799.                 {
  800.                     mips.cp0r[ CP0_BADVADDR ] = adr;
  801.                     mips_exception( EXC_ADEL );
  802.                 }
  803.                 else
  804.                 {    
  805.                     mips.r[ INS_RT( mips.op ) ] = MIPS_BYTE_EXTEND( cpu_readmem32lew( adr ) );
  806.                     mips_advance_pc();
  807.                 }
  808.             }
  809.             break;
  810.         case OP_LH:
  811.             if( mips.cp0r[ CP0_SR ] & SR_RE || mips.cp0r[ CP0_SR ] & SR_ISC )
  812.             {
  813.                 /* not implemented */
  814.                 mips_advance_pc();
  815.             }
  816.             else
  817.             {
  818.                 UINT32 adr;
  819.                 adr = mips.r[ INS_RS( mips.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  820.                 if( ( adr & ( ( ( mips.cp0r[ CP0_SR ] & 0x02 ) << 31 ) | 1 ) ) != 0 )
  821.                 {
  822.                     mips.cp0r[ CP0_BADVADDR ] = adr;
  823.                     mips_exception( EXC_ADEL );
  824.                 }
  825.                 else
  826.                 {
  827.                     mips.r[ INS_RT( mips.op ) ] = MIPS_WORD_EXTEND( cpu_readmem32lew_word( adr ) );
  828.                     mips_advance_pc();
  829.                 }
  830.             }
  831.             break;
  832.         case OP_LWL:
  833.             mips_stop();
  834.             /* not implemented */
  835.             mips_advance_pc();
  836.             break;
  837.         case OP_LW:
  838.             if( mips.cp0r[ CP0_SR ] & SR_RE || mips.cp0r[ CP0_SR ] & SR_ISC )
  839.             {
  840.                 /* not implemented */
  841.                 mips_advance_pc();
  842.             }
  843.             else
  844.             {
  845.                 UINT32 adr;
  846.                 adr = mips.r[ INS_RS( mips.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  847.                 if( ( adr & ( ( ( mips.cp0r[ CP0_SR ] & 0x02 ) << 31 ) | 3 ) ) != 0 )
  848.                 {
  849.                     mips.cp0r[ CP0_BADVADDR ] = adr;
  850.                     mips_exception( EXC_ADEL );
  851.                 }
  852.                 else
  853.                 {
  854.                     mips.r[ INS_RT( mips.op ) ] = cpu_readmem32lew_dword( adr );
  855.                     mips_advance_pc();
  856.                 }
  857.             }
  858.             break;
  859.         case OP_LBU:
  860.             if( mips.cp0r[ CP0_SR ] & SR_RE || mips.cp0r[ CP0_SR ] & SR_ISC )
  861.             {
  862.                 /* not implemented */
  863.                 mips_advance_pc();
  864.             }
  865.             else
  866.             {
  867.                 UINT32 adr;
  868.                 adr = mips.r[ INS_RS( mips.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  869.                 if( ( adr & ( ( mips.cp0r[ CP0_SR ] & 0x02 ) << 31 ) ) != 0 )
  870.                 {
  871.                     mips.cp0r[ CP0_BADVADDR ] = adr;
  872.                     mips_exception( EXC_ADEL );
  873.                 }
  874.                 else
  875.                 {
  876.                     mips.r[ INS_RT( mips.op ) ] = cpu_readmem32lew( adr );
  877.                     mips_advance_pc();
  878.                 }
  879.             }
  880.             break;
  881.         case OP_LHU:
  882.             if( mips.cp0r[ CP0_SR ] & SR_RE || mips.cp0r[ CP0_SR ] & SR_ISC )
  883.             {
  884.                 /* not implemented */
  885.                 mips_advance_pc();
  886.             }
  887.             else
  888.             {
  889.                 UINT32 adr;
  890.                 adr = mips.r[ INS_RS( mips.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  891.                 if( ( adr & ( ( ( mips.cp0r[ CP0_SR ] & 0x02 ) << 31 ) | 1 ) ) != 0 )
  892.                 {
  893.                     mips.cp0r[ CP0_BADVADDR ] = adr;
  894.                     mips_exception( EXC_ADEL );
  895.                 }
  896.                 else
  897.                 {
  898.                     mips.r[ INS_RT( mips.op ) ] = cpu_readmem32lew_word( adr );
  899.                     mips_advance_pc();
  900.                 }
  901.             }
  902.             break;
  903.         case OP_LWR:
  904.             mips_stop();
  905.             /* not implemented */
  906.             mips_advance_pc();
  907.             break;
  908.         case OP_SB:
  909.             if( mips.cp0r[ CP0_SR ] & SR_RE || mips.cp0r[ CP0_SR ] & SR_ISC )
  910.             {
  911.                 /* not implemented */
  912.                 mips_advance_pc();
  913.             }
  914.             else
  915.             {
  916.                 UINT32 adr;
  917.                 adr = mips.r[ INS_RS( mips.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  918.                 if( ( adr & ( ( mips.cp0r[ CP0_SR ] & 0x02 ) << 31 ) ) != 0 )
  919.                 {
  920.                     mips.cp0r[ CP0_BADVADDR ] = adr;
  921.                     mips_exception( EXC_ADES );
  922.                 }
  923.                 else
  924.                 {
  925.                     cpu_writemem32lew( adr, mips.r[ INS_RT( mips.op ) ] );
  926.                     mips_advance_pc();
  927.                 }
  928.             }
  929.             break;
  930.         case OP_SH:
  931.             if( mips.cp0r[ CP0_SR ] & SR_RE || mips.cp0r[ CP0_SR ] & SR_ISC )
  932.             {
  933.                 /* not implemented */
  934.                 mips_advance_pc();
  935.             }
  936.             else
  937.             {
  938.                 UINT32 adr;
  939.                 adr = mips.r[ INS_RS( mips.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  940.                 if( ( adr & ( ( ( mips.cp0r[ CP0_SR ] & 0x02 ) << 31 ) | 1 ) ) != 0 )
  941.                 {
  942.                     mips.cp0r[ CP0_BADVADDR ] = adr;
  943.                     mips_exception( EXC_ADES );
  944.                 }
  945.                 else
  946.                 {
  947.                     cpu_writemem32lew_word( adr, mips.r[ INS_RT( mips.op ) ] );
  948.                     mips_advance_pc();
  949.                 }
  950.             }
  951.             break;
  952.         case OP_SWL:
  953.             /* not implemented */
  954.             mips_stop();
  955.             mips_advance_pc();
  956.             break;
  957.         case OP_SW:
  958.             if( mips.cp0r[ CP0_SR ] & SR_RE || mips.cp0r[ CP0_SR ] & SR_ISC )
  959.             {
  960.                 /* not implemented */
  961.                 mips_advance_pc();
  962.             }
  963.             else
  964.             {
  965.                 UINT32 adr;
  966.                 adr = mips.r[ INS_RS( mips.op ) ] + MIPS_WORD_EXTEND( INS_IMMEDIATE( mips.op ) );
  967.                 if( ( adr & ( ( ( mips.cp0r[ CP0_SR ] & 0x02 ) << 31 ) | 3 ) ) != 0 )
  968.                 {
  969.                     mips.cp0r[ CP0_BADVADDR ] = adr;
  970.                     mips_exception( EXC_ADES );
  971.                 }
  972.                 else
  973.                 {
  974.                     cpu_writemem32lew_dword( adr, mips.r[ INS_RT( mips.op ) ] );
  975.                     mips_advance_pc();
  976.                 }
  977.             }
  978.             break;
  979.         case OP_SWR:
  980.             /* not implemented */
  981.             mips_stop();
  982.             mips_advance_pc();
  983.             break;
  984.         case OP_LWC1:
  985.             /* not implemented */
  986.             mips_stop();
  987.             mips_advance_pc();
  988.             break;
  989.         case OP_LWC2:
  990.             /* not implemented */
  991.             mips_stop();
  992.             mips_advance_pc();
  993.             break;
  994.         case OP_SWC1:
  995.             /* not implemented */
  996.             mips_stop();
  997.             mips_advance_pc();
  998.             break;
  999.         case OP_SWC2:
  1000.             /* not implemented */
  1001.             mips_stop();
  1002.             mips_advance_pc();
  1003.             break;
  1004.         default:
  1005.             mips_exception( EXC_RI );
  1006.             break;
  1007.         }
  1008.         mips_ICount--;
  1009.     } while( mips_ICount > 0 );
  1010.  
  1011.     return cycles - mips_ICount;
  1012. }
  1013.  
  1014. unsigned mips_get_context( void *dst )
  1015. {
  1016.     if( dst )
  1017.     {
  1018.         *(mips_cpu_context *)dst = mips;
  1019.     }
  1020.     return sizeof( mips_cpu_context );
  1021. }
  1022.  
  1023. void mips_set_context( void *src )
  1024. {
  1025.     if( src )
  1026.     {
  1027.         mips = *(mips_cpu_context *)src;
  1028.         change_pc32( mips.nextpc );
  1029.     }
  1030. }
  1031.  
  1032. unsigned mips_get_pc( void )
  1033. {
  1034.     return mips.pc;
  1035. }
  1036.  
  1037. unsigned mips_get_op_counter( void )
  1038. {
  1039.     return mips.nextpc;
  1040. }
  1041.  
  1042. void mips_set_pc( unsigned val )
  1043. {
  1044.     mips_set_nextpc( val );
  1045.     mips_advance_pc();
  1046. }
  1047.  
  1048. unsigned mips_get_sp(void)
  1049. {
  1050.     /* because there is no hardware stack and the pipeline causes the cpu to execute the
  1051.     instruction after a subroutine call before the subroutine there is little chance of
  1052.     cmd_step_over() in mamedbg.c working. */
  1053.     return 0;
  1054. }
  1055.  
  1056. void mips_set_sp( unsigned val )
  1057. {
  1058.     /* no hardware stack */
  1059. }
  1060.  
  1061. unsigned mips_get_reg( int regnum )
  1062. {
  1063.     switch( regnum )
  1064.     {
  1065.     case MIPS_PC:        return mips.pc;
  1066.     case MIPS_OC:        return mips.nextpc;
  1067.     case MIPS_HI:        return mips.hi;
  1068.     case MIPS_LO:        return mips.lo;
  1069.     case MIPS_R0:        return mips.r[ 0 ];
  1070.     case MIPS_R1:        return mips.r[ 1 ];
  1071.     case MIPS_R2:        return mips.r[ 2 ];
  1072.     case MIPS_R3:        return mips.r[ 3 ];
  1073.     case MIPS_R4:        return mips.r[ 4 ];
  1074.     case MIPS_R5:        return mips.r[ 5 ];
  1075.     case MIPS_R6:        return mips.r[ 6 ];
  1076.     case MIPS_R7:        return mips.r[ 7 ];
  1077.     case MIPS_R8:        return mips.r[ 8 ];
  1078.     case MIPS_R9:        return mips.r[ 9 ];
  1079.     case MIPS_R10:        return mips.r[ 10 ];
  1080.     case MIPS_R11:        return mips.r[ 11 ];
  1081.     case MIPS_R12:        return mips.r[ 12 ];
  1082.     case MIPS_R13:        return mips.r[ 13 ];
  1083.     case MIPS_R14:        return mips.r[ 14 ];
  1084.     case MIPS_R15:        return mips.r[ 15 ];
  1085.     case MIPS_R16:        return mips.r[ 16 ];
  1086.     case MIPS_R17:        return mips.r[ 17 ];
  1087.     case MIPS_R18:        return mips.r[ 18 ];
  1088.     case MIPS_R19:        return mips.r[ 19 ];
  1089.     case MIPS_R20:        return mips.r[ 20 ];
  1090.     case MIPS_R21:        return mips.r[ 21 ];
  1091.     case MIPS_R22:        return mips.r[ 22 ];
  1092.     case MIPS_R23:        return mips.r[ 23 ];
  1093.     case MIPS_R24:        return mips.r[ 24 ];
  1094.     case MIPS_R25:        return mips.r[ 25 ];
  1095.     case MIPS_R26:        return mips.r[ 26 ];
  1096.     case MIPS_R27:        return mips.r[ 27 ];
  1097.     case MIPS_R28:        return mips.r[ 28 ];
  1098.     case MIPS_R29:        return mips.r[ 29 ];
  1099.     case MIPS_R30:        return mips.r[ 30 ];
  1100.     case MIPS_R31:        return mips.r[ 31 ];
  1101.     case MIPS_CP0R0:    return mips.cp0r[ 0 ];
  1102.     case MIPS_CP0R1:    return mips.cp0r[ 1 ];
  1103.     case MIPS_CP0R2:    return mips.cp0r[ 2 ];
  1104.     case MIPS_CP0R3:    return mips.cp0r[ 3 ];
  1105.     case MIPS_CP0R4:    return mips.cp0r[ 4 ];
  1106.     case MIPS_CP0R5:    return mips.cp0r[ 5 ];
  1107.     case MIPS_CP0R6:    return mips.cp0r[ 6 ];
  1108.     case MIPS_CP0R7:    return mips.cp0r[ 7 ];
  1109.     case MIPS_CP0R8:    return mips.cp0r[ 8 ];
  1110.     case MIPS_CP0R9:    return mips.cp0r[ 9 ];
  1111.     case MIPS_CP0R10:    return mips.cp0r[ 10 ];
  1112.     case MIPS_CP0R11:    return mips.cp0r[ 11 ];
  1113.     case MIPS_CP0R12:    return mips.cp0r[ 12 ];
  1114.     case MIPS_CP0R13:    return mips.cp0r[ 13 ];
  1115.     case MIPS_CP0R14:    return mips.cp0r[ 14 ];
  1116.     case MIPS_CP0R15:    return mips.cp0r[ 15 ];
  1117.     case MIPS_CP0R16:    return mips.cp0r[ 16 ];
  1118.     case MIPS_CP0R17:    return mips.cp0r[ 17 ];
  1119.     case MIPS_CP0R18:    return mips.cp0r[ 18 ];
  1120.     case MIPS_CP0R19:    return mips.cp0r[ 19 ];
  1121.     case MIPS_CP0R20:    return mips.cp0r[ 20 ];
  1122.     case MIPS_CP0R21:    return mips.cp0r[ 21 ];
  1123.     case MIPS_CP0R22:    return mips.cp0r[ 22 ];
  1124.     case MIPS_CP0R23:    return mips.cp0r[ 23 ];
  1125.     case MIPS_CP0R24:    return mips.cp0r[ 24 ];
  1126.     case MIPS_CP0R25:    return mips.cp0r[ 25 ];
  1127.     case MIPS_CP0R26:    return mips.cp0r[ 26 ];
  1128.     case MIPS_CP0R27:    return mips.cp0r[ 27 ];
  1129.     case MIPS_CP0R28:    return mips.cp0r[ 28 ];
  1130.     case MIPS_CP0R29:    return mips.cp0r[ 29 ];
  1131.     case MIPS_CP0R30:    return mips.cp0r[ 30 ];
  1132.     case MIPS_CP0R31:    return mips.cp0r[ 31 ];
  1133.     }
  1134.     return 0;
  1135. }
  1136.  
  1137. void mips_set_reg( int regnum, unsigned val )
  1138. {
  1139.     switch( regnum )
  1140.     {
  1141.     case MIPS_PC:        mips_set_pc( val );    break;
  1142.     case MIPS_OC:        mips_set_nextpc( val );    break;
  1143.     case MIPS_HI:        mips.hi = val;        break;
  1144.     case MIPS_LO:        mips.lo = val;        break;
  1145.     case MIPS_R0:        mips.r[ 0 ] = val;    break;
  1146.     case MIPS_R1:        mips.r[ 1 ] = val;    break;
  1147.     case MIPS_R2:        mips.r[ 2 ] = val;    break;
  1148.     case MIPS_R3:        mips.r[ 3 ] = val;    break;
  1149.     case MIPS_R4:        mips.r[ 4 ] = val;    break;
  1150.     case MIPS_R5:        mips.r[ 5 ] = val;    break;
  1151.     case MIPS_R6:        mips.r[ 6 ] = val;    break;
  1152.     case MIPS_R7:        mips.r[ 7 ] = val;    break;
  1153.     case MIPS_R8:        mips.r[ 8 ] = val;    break;
  1154.     case MIPS_R9:        mips.r[ 9 ] = val;    break;
  1155.     case MIPS_R10:        mips.r[ 10 ] = val;    break;
  1156.     case MIPS_R11:        mips.r[ 11 ] = val;    break;
  1157.     case MIPS_R12:        mips.r[ 12 ] = val;    break;
  1158.     case MIPS_R13:        mips.r[ 13 ] = val;    break;
  1159.     case MIPS_R14:        mips.r[ 14 ] = val;    break;
  1160.     case MIPS_R15:        mips.r[ 15 ] = val;    break;
  1161.     case MIPS_R16:        mips.r[ 16 ] = val;    break;
  1162.     case MIPS_R17:        mips.r[ 17 ] = val;    break;
  1163.     case MIPS_R18:        mips.r[ 18 ] = val;    break;
  1164.     case MIPS_R19:        mips.r[ 19 ] = val;    break;
  1165.     case MIPS_R20:        mips.r[ 20 ] = val;    break;
  1166.     case MIPS_R21:        mips.r[ 21 ] = val;    break;
  1167.     case MIPS_R22:        mips.r[ 22 ] = val;    break;
  1168.     case MIPS_R23:        mips.r[ 23 ] = val;    break;
  1169.     case MIPS_R24:        mips.r[ 24 ] = val;    break;
  1170.     case MIPS_R25:        mips.r[ 25 ] = val;    break;
  1171.     case MIPS_R26:        mips.r[ 26 ] = val;    break;
  1172.     case MIPS_R27:        mips.r[ 27 ] = val;    break;
  1173.     case MIPS_R28:        mips.r[ 28 ] = val;    break;
  1174.     case MIPS_R29:        mips.r[ 29 ] = val;    break;
  1175.     case MIPS_R30:        mips.r[ 30 ] = val;    break;
  1176.     case MIPS_R31:        mips.r[ 31 ] = val;    break;
  1177.     case MIPS_CP0R0:    mips.cp0r[ 0 ] = val;    break;
  1178.     case MIPS_CP0R1:    mips.cp0r[ 1 ] = val;    break;
  1179.     case MIPS_CP0R2:    mips.cp0r[ 2 ] = val;    break;
  1180.     case MIPS_CP0R3:    mips.cp0r[ 3 ] = val;    break;
  1181.     case MIPS_CP0R4:    mips.cp0r[ 4 ] = val;    break;
  1182.     case MIPS_CP0R5:    mips.cp0r[ 5 ] = val;    break;
  1183.     case MIPS_CP0R6:    mips.cp0r[ 6 ] = val;    break;
  1184.     case MIPS_CP0R7:    mips.cp0r[ 7 ] = val;    break;
  1185.     case MIPS_CP0R8:    mips.cp0r[ 8 ] = val;    break;
  1186.     case MIPS_CP0R9:    mips.cp0r[ 9 ] = val;    break;
  1187.     case MIPS_CP0R10:    mips.cp0r[ 10 ] = val;    break;
  1188.     case MIPS_CP0R11:    mips.cp0r[ 11 ] = val;    break;
  1189.     case MIPS_CP0R12:    mips.cp0r[ 12 ] = val;    break;
  1190.     case MIPS_CP0R13:    mips.cp0r[ 13 ] = val;    break;
  1191.     case MIPS_CP0R14:    mips.cp0r[ 14 ] = val;    break;
  1192.     case MIPS_CP0R15:    mips.cp0r[ 15 ] = val;    break;
  1193.     case MIPS_CP0R16:    mips.cp0r[ 16 ] = val;    break;
  1194.     case MIPS_CP0R17:    mips.cp0r[ 17 ] = val;    break;
  1195.     case MIPS_CP0R18:    mips.cp0r[ 18 ] = val;    break;
  1196.     case MIPS_CP0R19:    mips.cp0r[ 19 ] = val;    break;
  1197.     case MIPS_CP0R20:    mips.cp0r[ 20 ] = val;    break;
  1198.     case MIPS_CP0R21:    mips.cp0r[ 21 ] = val;    break;
  1199.     case MIPS_CP0R22:    mips.cp0r[ 22 ] = val;    break;
  1200.     case MIPS_CP0R23:    mips.cp0r[ 23 ] = val;    break;
  1201.     case MIPS_CP0R24:    mips.cp0r[ 24 ] = val;    break;
  1202.     case MIPS_CP0R25:    mips.cp0r[ 25 ] = val;    break;
  1203.     case MIPS_CP0R26:    mips.cp0r[ 26 ] = val;    break;
  1204.     case MIPS_CP0R27:    mips.cp0r[ 27 ] = val;    break;
  1205.     case MIPS_CP0R28:    mips.cp0r[ 28 ] = val;    break;
  1206.     case MIPS_CP0R29:    mips.cp0r[ 29 ] = val;    break;
  1207.     case MIPS_CP0R30:    mips.cp0r[ 30 ] = val;    break;
  1208.     case MIPS_CP0R31:    mips.cp0r[ 31 ] = val;    break;
  1209.     }
  1210. }
  1211.  
  1212. void mips_set_nmi_line( int state )
  1213. {
  1214.     switch( state )
  1215.     {
  1216.         case CLEAR_LINE:
  1217.             return;
  1218.         case ASSERT_LINE:
  1219.             return;
  1220.         default:
  1221.             return;
  1222.     }
  1223. }
  1224.  
  1225. void mips_set_irq_line( int irqline, int state )
  1226. {
  1227.     switch( state )
  1228.     {
  1229.         case CLEAR_LINE:
  1230.             return;
  1231.         case ASSERT_LINE:
  1232.             return;
  1233.         default:
  1234.             return;
  1235.     }
  1236. }
  1237.  
  1238. void mips_set_irq_callback(int (*callback)(int irqline))
  1239. {
  1240. }
  1241.  
  1242. /****************************************************************************
  1243.  * Return a formatted string for a register
  1244.  ****************************************************************************/
  1245.  
  1246. const char *mips_info( void *context, int regnum )
  1247. {
  1248.     static char buffer[ 64 ][ 47 + 1 ];
  1249.     static int which = 0;
  1250.     mips_cpu_context *r = context;
  1251.  
  1252.     which = ++which % 64;
  1253.     buffer[ which ][ 0 ] = '\0';
  1254.     if( !context )
  1255.     {
  1256.         static mips_cpu_context tmp;
  1257.         mips_get_context( &tmp );
  1258.         r = &tmp;
  1259.     }
  1260.  
  1261.     switch( regnum )
  1262.     {
  1263.     case CPU_INFO_REG + MIPS_PC:        sprintf( buffer[ which ], "pc      :%08x", r->pc );                break;
  1264.     case CPU_INFO_REG + MIPS_OC:        sprintf( buffer[ which ], "oc      :%08x", r->nextpc );            break;
  1265.     case CPU_INFO_REG + MIPS_HI:        sprintf( buffer[ which ], "hi      :%08x", r->hi );                break;
  1266.     case CPU_INFO_REG + MIPS_LO:        sprintf( buffer[ which ], "lo      :%08x", r->lo );                break;
  1267.     case CPU_INFO_REG + MIPS_R0:        sprintf( buffer[ which ], "zero    :%08x", r->r[ 0 ] );            break;
  1268.     case CPU_INFO_REG + MIPS_R1:        sprintf( buffer[ which ], "at      :%08x", r->r[ 1 ] );            break;
  1269.     case CPU_INFO_REG + MIPS_R2:        sprintf( buffer[ which ], "v0      :%08x", r->r[ 2 ] );            break;
  1270.     case CPU_INFO_REG + MIPS_R3:        sprintf( buffer[ which ], "v1      :%08x", r->r[ 3 ] );            break;
  1271.     case CPU_INFO_REG + MIPS_R4:        sprintf( buffer[ which ], "a0      :%08x", r->r[ 4 ] );            break;
  1272.     case CPU_INFO_REG + MIPS_R5:        sprintf( buffer[ which ], "a1      :%08x", r->r[ 5 ] );            break;
  1273.     case CPU_INFO_REG + MIPS_R6:        sprintf( buffer[ which ], "a2      :%08x", r->r[ 6 ] );            break;
  1274.     case CPU_INFO_REG + MIPS_R7:        sprintf( buffer[ which ], "a3      :%08x", r->r[ 7 ] );            break;
  1275.     case CPU_INFO_REG + MIPS_R8:        sprintf( buffer[ which ], "t0      :%08x", r->r[ 8 ] );            break;
  1276.     case CPU_INFO_REG + MIPS_R9:        sprintf( buffer[ which ], "t1      :%08x", r->r[ 9 ] );            break;
  1277.     case CPU_INFO_REG + MIPS_R10:        sprintf( buffer[ which ], "t2      :%08x", r->r[ 10 ] );        break;
  1278.     case CPU_INFO_REG + MIPS_R11:        sprintf( buffer[ which ], "t3      :%08x", r->r[ 11 ] );        break;
  1279.     case CPU_INFO_REG + MIPS_R12:        sprintf( buffer[ which ], "t4      :%08x", r->r[ 12 ] );        break;
  1280.     case CPU_INFO_REG + MIPS_R13:        sprintf( buffer[ which ], "t5      :%08x", r->r[ 13 ] );        break;
  1281.     case CPU_INFO_REG + MIPS_R14:        sprintf( buffer[ which ], "t6      :%08x", r->r[ 14 ] );        break;
  1282.     case CPU_INFO_REG + MIPS_R15:        sprintf( buffer[ which ], "t7      :%08x", r->r[ 15 ] );        break;
  1283.     case CPU_INFO_REG + MIPS_R16:        sprintf( buffer[ which ], "s0      :%08x", r->r[ 16 ] );        break;
  1284.     case CPU_INFO_REG + MIPS_R17:        sprintf( buffer[ which ], "s1      :%08x", r->r[ 17 ] );        break;
  1285.     case CPU_INFO_REG + MIPS_R18:        sprintf( buffer[ which ], "s2      :%08x", r->r[ 18 ] );        break;
  1286.     case CPU_INFO_REG + MIPS_R19:        sprintf( buffer[ which ], "s3      :%08x", r->r[ 19 ] );        break;
  1287.     case CPU_INFO_REG + MIPS_R20:        sprintf( buffer[ which ], "s4      :%08x", r->r[ 20 ] );        break;
  1288.     case CPU_INFO_REG + MIPS_R21:        sprintf( buffer[ which ], "s5      :%08x", r->r[ 21 ] );        break;
  1289.     case CPU_INFO_REG + MIPS_R22:        sprintf( buffer[ which ], "s6      :%08x", r->r[ 22 ] );        break;
  1290.     case CPU_INFO_REG + MIPS_R23:        sprintf( buffer[ which ], "s7      :%08x", r->r[ 23 ] );        break;
  1291.     case CPU_INFO_REG + MIPS_R24:        sprintf( buffer[ which ], "t8      :%08x", r->r[ 24 ] );        break;
  1292.     case CPU_INFO_REG + MIPS_R25:        sprintf( buffer[ which ], "t9      :%08x", r->r[ 25 ] );        break;
  1293.     case CPU_INFO_REG + MIPS_R26:        sprintf( buffer[ which ], "k0      :%08x", r->r[ 26 ] );        break;
  1294.     case CPU_INFO_REG + MIPS_R27:        sprintf( buffer[ which ], "k1      :%08x", r->r[ 27 ] );        break;
  1295.     case CPU_INFO_REG + MIPS_R28:        sprintf( buffer[ which ], "gp      :%08x", r->r[ 28 ] );        break;
  1296.     case CPU_INFO_REG + MIPS_R29:        sprintf( buffer[ which ], "sp      :%08x", r->r[ 29 ] );        break;
  1297.     case CPU_INFO_REG + MIPS_R30:        sprintf( buffer[ which ], "fp      :%08x", r->r[ 30 ] );        break;
  1298.     case CPU_INFO_REG + MIPS_R31:        sprintf( buffer[ which ], "ra      :%08x", r->r[ 31 ] );        break;
  1299.     case CPU_INFO_REG + MIPS_CP0R0:        sprintf( buffer[ which ], "Index   :%08x", r->cp0r[ 0 ] );        break;
  1300.     case CPU_INFO_REG + MIPS_CP0R1:        sprintf( buffer[ which ], "Random  :%08x", r->cp0r[ 1 ] );        break;
  1301.     case CPU_INFO_REG + MIPS_CP0R2:        sprintf( buffer[ which ], "EntryLo :%08x", r->cp0r[ 2 ] );        break;
  1302.     case CPU_INFO_REG + MIPS_CP0R3:        sprintf( buffer[ which ], "cp0r3   :%08x", r->cp0r[ 3 ] );        break;
  1303.     case CPU_INFO_REG + MIPS_CP0R4:        sprintf( buffer[ which ], "Context :%08x", r->cp0r[ 4 ] );        break;
  1304.     case CPU_INFO_REG + MIPS_CP0R5:        sprintf( buffer[ which ], "cp0r5   :%08x", r->cp0r[ 5 ] );        break;
  1305.     case CPU_INFO_REG + MIPS_CP0R6:        sprintf( buffer[ which ], "cp0r6   :%08x", r->cp0r[ 6 ] );        break;
  1306.     case CPU_INFO_REG + MIPS_CP0R7:        sprintf( buffer[ which ], "cp0r7   :%08x", r->cp0r[ 7 ] );        break;
  1307.     case CPU_INFO_REG + MIPS_CP0R8:        sprintf( buffer[ which ], "BadVAddr:%08x", r->cp0r[ 8 ] );        break;
  1308.     case CPU_INFO_REG + MIPS_CP0R9:        sprintf( buffer[ which ], "cp0r9   :%08x", r->cp0r[ 9 ] );        break;
  1309.     case CPU_INFO_REG + MIPS_CP0R10:    sprintf( buffer[ which ], "EntryHi :%08x", r->cp0r[ 10 ] );        break;
  1310.     case CPU_INFO_REG + MIPS_CP0R11:    sprintf( buffer[ which ], "cp0r11  :%08x", r->cp0r[ 11 ] );        break;
  1311.     case CPU_INFO_REG + MIPS_CP0R12:    sprintf( buffer[ which ], "SR      :%08x", r->cp0r[ 12 ] );        break;
  1312.     case CPU_INFO_REG + MIPS_CP0R13:    sprintf( buffer[ which ], "Cause   :%08x", r->cp0r[ 13 ] );        break;
  1313.     case CPU_INFO_REG + MIPS_CP0R14:    sprintf( buffer[ which ], "EPC     :%08x", r->cp0r[ 14 ] );        break;
  1314.     case CPU_INFO_REG + MIPS_CP0R15:    sprintf( buffer[ which ], "PRId    :%08x", r->cp0r[ 15 ] );        break;
  1315.     case CPU_INFO_REG + MIPS_CP0R16:    sprintf( buffer[ which ], "cp0r16  :%08x", r->cp0r[ 16 ] );        break;
  1316.     case CPU_INFO_REG + MIPS_CP0R17:    sprintf( buffer[ which ], "cp0r17  :%08x", r->cp0r[ 17 ] );        break;
  1317.     case CPU_INFO_REG + MIPS_CP0R18:    sprintf( buffer[ which ], "cp0r18  :%08x", r->cp0r[ 18 ] );        break;
  1318.     case CPU_INFO_REG + MIPS_CP0R19:    sprintf( buffer[ which ], "cp0r19  :%08x", r->cp0r[ 19 ] );        break;
  1319.     case CPU_INFO_REG + MIPS_CP0R20:    sprintf( buffer[ which ], "cp0r20  :%08x", r->cp0r[ 20 ] );        break;
  1320.     case CPU_INFO_REG + MIPS_CP0R21:    sprintf( buffer[ which ], "cp0r21  :%08x", r->cp0r[ 21 ] );        break;
  1321.     case CPU_INFO_REG + MIPS_CP0R22:    sprintf( buffer[ which ], "cp0r22  :%08x", r->cp0r[ 22 ] );        break;
  1322.     case CPU_INFO_REG + MIPS_CP0R23:    sprintf( buffer[ which ], "cp0r23  :%08x", r->cp0r[ 23 ] );        break;
  1323.     case CPU_INFO_REG + MIPS_CP0R24:    sprintf( buffer[ which ], "cp0r24  :%08x", r->cp0r[ 24 ] );        break;
  1324.     case CPU_INFO_REG + MIPS_CP0R25:    sprintf( buffer[ which ], "cp0r25  :%08x", r->cp0r[ 25 ] );        break;
  1325.     case CPU_INFO_REG + MIPS_CP0R26:    sprintf( buffer[ which ], "cp0r26  :%08x", r->cp0r[ 26 ] );        break;
  1326.     case CPU_INFO_REG + MIPS_CP0R27:    sprintf( buffer[ which ], "cp0r27  :%08x", r->cp0r[ 27 ] );        break;
  1327.     case CPU_INFO_REG + MIPS_CP0R28:    sprintf( buffer[ which ], "cp0r28  :%08x", r->cp0r[ 28 ] );        break;
  1328.     case CPU_INFO_REG + MIPS_CP0R29:    sprintf( buffer[ which ], "cp0r29  :%08x", r->cp0r[ 29 ] );        break;
  1329.     case CPU_INFO_REG + MIPS_CP0R30:    sprintf( buffer[ which ], "cp0r30  :%08x", r->cp0r[ 30 ] );        break;
  1330.     case CPU_INFO_REG + MIPS_CP0R31:    sprintf( buffer[ which ], "cp0r31  :%08x", r->cp0r[ 31 ] );        break;
  1331.     case CPU_INFO_FLAGS:        return "";
  1332.     case CPU_INFO_NAME:            return "PSX";
  1333.     case CPU_INFO_FAMILY:        return "MIPS";
  1334.     case CPU_INFO_VERSION:        return "1.0";
  1335.     case CPU_INFO_FILE:            return __FILE__;
  1336.     case CPU_INFO_CREDITS:        return "Copyright 2000 smf";
  1337.     case CPU_INFO_REG_LAYOUT:    return (const char*)mips_reg_layout;
  1338.     case CPU_INFO_WIN_LAYOUT:    return (const char*)mips_win_layout;
  1339.     }
  1340.     return buffer[ which ];
  1341. }
  1342.  
  1343. unsigned mips_dasm( char *buffer, UINT32 pc )
  1344. {
  1345.     unsigned ret;
  1346.     change_pc32( pc );
  1347. #ifdef MAME_DEBUG
  1348.     ret = DasmMIPS( buffer, pc );
  1349. #else
  1350.     sprintf( buffer, "$%08x", cpu_readop32( pc ) );
  1351.     ret = 4;
  1352. #endif
  1353.     change_pc32( mips.nextpc );
  1354.     return ret;
  1355. }
  1356.